/*
 * Josh Lindoo
 * Login ID : lind6441
 * CS-102, Winter 2013
 * Programming Assignment 5
 * LinkedList class: Basic Linked List using generics
 * 					
 */

public class LinkedList<T> {
	
	protected Node<T> head; //head node
	protected int numberOfItems; //count items
	
	//Default Constructor
	public LinkedList() {
		head = null;
		numberOfItems = 0;
	}
	
	
	/*
	 * Method: getNumberOfItems
	 * Purpose: Accessor for numberOfItems
	 * Parameters:	none
	 * Returns: int
	 */
	
	public int getNumberOfItems() {
		return numberOfItems;
	}
	
	
	/*
	 * Method: isEmpty
	 * Purpose: returns true/false value of whether the list is empty or not
	 * Parameters:	none
	 * Returns: boolean
	 */
	
	public boolean isEmpty() {
		return (numberOfItems == 0);
	}
	
	
	/*
	 * Method: add
	 * Purpose: adds an object at a given index
	 * Parameters:
	 * 		int index: index to add at
	 * 		T item:		object to add
	 * Returns: void
	 */
	
	public void add(int index, T item) {
		
		if(index < 0 || index > numberOfItems)
			throw new IndexOutOfBoundsException();
		
		Node<T> prevNode = null; //track prev node
		Node<T> currNode = head; //track curr node
		
		while(index > 0) {
			prevNode = currNode;
			currNode = currNode.getNext();
			index--;
		}
		
		Node<T> splice = new Node<T>(item); //node to add
		splice.setNext(currNode);
		
		if(prevNode == null)
			head = splice;
		else
			prevNode.setNext(splice);
		
		numberOfItems++;
	}
	
	
	/*
	 * Method: remove
	 * Purpose: remove object from list at a given index
	 * Parameters:
	 * 		int index: index to remove from
	 * Returns:
	 * 		T : object that was removed
	 */
	
	public T remove(int index) {
		
		if(index < 0 || index >= numberOfItems)
			throw new IndexOutOfBoundsException();
		
		Node<T> prevNode = null; //track prev node
		Node<T> currNode = head; //track curr node
		
		//count down to index
		while(index > 0) {
			prevNode = currNode;
			currNode = currNode.getNext();
			index--;
		}
		
		if(prevNode == null)
			head = currNode.getNext();
		else
			prevNode.setNext(currNode.getNext());
		
		numberOfItems--;
		
		return currNode.getDatum();
	}
	
	
	/*
	 * Method: printList
	 * Purpose: print list contents
	 * Parameters:	none
	 * Returns: void
	 */
	
	public void printList() {
		
		Node<T> currNode = head; //track curr node
		
		while(currNode != null) {
			System.out.println(currNode.getDatum());
			currNode = currNode.getNext();
		}
	}
	
}
